package modules

import (
	"github.com/go-redis/redis/v8"
	"missevanbot/models"
	"missevanbot/utils"
)

const (
	StatusNon = iota
	StatusDown
	StatusAlive
	StatusOnline
)

const PubSub = "rooms"

func RoomConfigs() []models.RoomConfig {
	keys := rdb.Keys(ctx, Prefix+"rooms*").Val()

	rooms := make([]models.RoomConfig, len(keys))
	for _, key := range keys {
		raw := rdb.HGetAll(ctx, key).Val()

		rooms = append(rooms, models.RoomConfig{
			ID:     utils.MustAtoi(raw["id"]),
			Alias:  raw["alias"],
			Enable: raw["enable"] == "true",
			Watch:  raw["watch"] == "true",
			Cookie: utils.MustAtoi(raw["cookie"]),
		})
	}
	return rooms
}

func SetRoomConfig(room models.RoomConfig) {
	key := Prefix + "rooms:" + utils.Itoa(room.ID) // missevan:rooms:[RoomID]
	rdb.HSet(ctx, key, map[string]interface{}{
		"id":     room.ID,
		"alias":  room.Alias,
		"enable": room.Enable,
		"watch":  room.Watch,
		"cookie": room.Cookie,
	})
}

// RoomStatus returns status of the bot in particular live room.
// Status includes Down, Alive and Online.
func RoomStatus(rid int64) int {
	key := Prefix + "rooms:" + utils.Itoa(rid) // missevan:rooms:[RoomID]
	if rdb.Exists(ctx, key).Val() <= 0 {
		return StatusNon
	}

	key = PrefixAlive + utils.Itoa(rid) // missevan:alive:[RoomID]
	alive := rdb.Exists(ctx, key).Val() > 0

	key = PrefixOnline + utils.Itoa(rid) // missevan:online:[RoomID]
	online := rdb.Exists(ctx, key).Val() > 0

	switch {
	case online:
		return StatusOnline
	case alive:
		return StatusAlive
	default:
		return StatusDown
	}
}

// Subscribe subscribes the live room configuration channel to receive the new configurations
// and returns the Go read-only channel.
func Subscribe() (<-chan *redis.Message, error) {
	sub := rdb.Subscribe(ctx, PubSub)
	_, err := sub.Receive(ctx)
	if err != nil {
		return nil, err
	}
	return sub.Channel(), nil
}
